package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.util.ArrayList;

public class Manager {
	ArrayList<Pixel> pixels;
	ArrayList<Relationship> relationships;
	Frame frame;
	boolean draw;
	int startX, startY, endX, endY;
	Pixel startPix, endPix;
	Graphics g;
	boolean erase;
	boolean invisible;
	PropertiesWindow properties;
	boolean clicking;
	boolean r1, r2, r3;
	Pixel rigid1, rigid2, rigid3, rigidPrev;
	int prevX, prevY;
	int index;

	public Manager() {
		pixels = new ArrayList<Pixel>();
		relationships = new ArrayList<Relationship>();
		draw = false;
		startX = startY = endX = endY = 0;
		g = null;
		invisible = false;
		clicking = false;
		rigid1 = rigid2 = rigid3 = null;
	}

	public void setComponents(Frame f, PropertiesWindow properties) {
		frame = f;
		this.properties = properties;
	}

	public void solidAct() {
		if (clicking && !erase) {
			int mX = MouseInfo.getPointerInfo().getLocation().x - frame.getX();
			int mY = MouseInfo.getPointerInfo().getLocation().y - frame.getY();
			if (index == -1) {
				index = pixels.size();
			}
			Pixel i = rigidPrev;
			if (mX > i.x - 10 && mX < prevX + 10 && mY > prevY - 10
					&& mY < prevY + 10) {
				return;
			}
			rigid1 = new Pixel(Color.red, mX, mY);
			pixels.add(rigid1);
			int elasticity;
			if (r2) {
				rigid3 = pixels.get(index + 1);
				elasticity = 1;
				if (properties.elastic.isSelected()) {
					elasticity = 20;
				}
				relationships.add(new Relationship(rigid3, rigid1,
						(int) Math.sqrt((rigid1.x - rigid3.x)
								* (rigid1.x - rigid3.x) + (rigid1.y - rigid3.y)
								* (rigid1.y - rigid3.y)), elasticity));
				relationships.get(relationships.size() - 1).invisible = true;
				relationships.get(relationships.size() - 1).manager = this;
			}
			if (r1) {
				rigid2 = pixels.get(index);
				elasticity = 1;
				if (properties.elastic.isSelected()) {
					elasticity = 20;
				}
				relationships.add(new Relationship(rigid2, rigid1,
						(int) Math.sqrt((rigid1.x - rigid2.x)
								* (rigid1.x - rigid2.x) + (rigid1.y - rigid2.y)
								* (rigid1.y - rigid2.y)), elasticity));
				relationships.get(relationships.size() - 1).invisible = true;
				relationships.get(relationships.size() - 1).manager = this;
				if (rigidPrev.x != -1) {
					relationships.add(new Relationship(rigidPrev, rigid1,
							(int) Math.sqrt((rigid1.x - rigidPrev.x)
									* (rigid1.x - rigidPrev.x)
									+ (rigid1.y - rigidPrev.y)
									* (rigid1.y - rigidPrev.y)), elasticity));
					relationships.get(relationships.size() - 1).manager = this;
				}
				r2 = true;

			}
			r1 = true;
			rigidPrev = rigid1;
		}
	}

	public void rigidAct() {
		if (clicking && !erase) {
			int mX = MouseInfo.getPointerInfo().getLocation().x - frame.getX();
			int mY = MouseInfo.getPointerInfo().getLocation().y - frame.getY();
				if (mX > prevX - 10 && mX < prevX + 10 && mY > prevY - 10
						&& mY < prevY + 10) {
					return;
				}
			if (r3) {
				rigid3 = pixels.get(pixels.size() - 2);
			}
			if (r2) {
				r3 = true;
				rigid2 = pixels.get(pixels.size() - 1);
			}
			rigid1 = new Pixel(Color.red, mX, mY);
			rigid1.weight = 0.1;
			pixels.add(rigid1);
			r2 = true;
			double elasticity;
			if (rigid2 != null) {
				elasticity = .1;
				if (properties.elastic.isSelected()) {
					elasticity = 2;
				}
				relationships.add(new Relationship(rigid1, rigid2, (int) Math
						.sqrt((prevX - mX) * (prevX - mX) + (prevY - mY)
								* (prevY - mY)), elasticity));
			}
			if (rigid3 != null) {
				elasticity = 1;
				if (properties.elastic.isSelected()) {
					elasticity = 20;
				}
				relationships.add(new Relationship(rigid3, rigid1,
						(int) Math.sqrt((rigid1.x - rigid3.x)
								* (rigid1.x - rigid3.x) + (rigid1.y - rigid3.y)
								* (rigid1.y - rigid3.y)), elasticity));
				relationships.get(relationships.size() - 1).ultraInvisible = true;
				relationships.get(relationships.size() - 1).manager = this;
			}
			prevX = mX;
			prevY = mY;

		}

	}

	public void draw(Graphics g) {
		invisible = properties.invisible.isSelected();
		this.g = g;
		if (pixels.size() == 0) {
			draw = true;
		}
		int mX = MouseInfo.getPointerInfo().getLocation().x - frame.getX();
		int mY = MouseInfo.getPointerInfo().getLocation().y - frame.getY();
		for (Pixel p : pixels) {
			if (p.x > mX - 5 && p.x < mX + 5 && p.y > mY - 5 && p.y < mY + 5) {
				if (p.clicked) {
					p.drawBorder(g, Color.red);
				} else {
					p.drawBorder(g, Color.black);
				}
			}
		}
		if (erase) {
			if (clicking) {
				g.setColor(Color.red);
				for (int i = 0; i < pixels.size(); i++) {
					Pixel p = pixels.get(i);
					if (p.x > mX - 5 && p.x < mX + 5 && p.y > mY - 5
							&& p.y < mY + 5) {
						for (int q = 0; q < relationships.size(); q++) {
							if (relationships.get(q).a == p
									|| relationships.get(q).b == p) {
								relationships.remove(q);
								q--;
							}
						}
						pixels.remove(p);
					}
				}
			} else {
				g.setColor(Color.black);
			}
			g.drawRect(mX - 4, mY - 4, 8, 8);

		}
		if (!draw) {
			for (Pixel p : pixels) {
				if (p.clicked) {
					p.clickAct(mX, mY);
				} else {
					p.act(frame.gravity.getValue());
				}
			}
			for (Relationship r : relationships) {
				r.act();
			}
		} else {
			if (properties.rigid.isSelected()) {
				rigidAct();
			} else if (properties.solid.isSelected()) {
				solidAct();
			} else {
				
				if (startX != 0) {
					g.drawLine(startX, startY, mX, mY);
				} else if (startPix != null) {
					g.drawLine((int) startPix.x, (int) startPix.y, mX, mY);
				}
			}
		}

		for (Pixel p : pixels) {
			p.draw(g, mX, mY);
		}
		for (Relationship r : relationships) {
			r.draw(g);
		}
	}

	public void click() {
		clicking = true;
		int x = MouseInfo.getPointerInfo().getLocation().x - frame.getX();
		int y = MouseInfo.getPointerInfo().getLocation().y - frame.getY();
		if (!draw) {
			for (Pixel p : pixels) {
				if (p.x > x - 5 && p.x < x + 5 && p.y > y - 5 && p.y < y + 5) {
					p.click(true);
				}
			}
		} else {
			Pixel p;
			if (erase) {
				for (int i = 0; i < pixels.size(); i++) {
					p = pixels.get(i);
					if (p.x > x - 5 && p.x < x + 5 && p.y > y - 5
							&& p.y < y + 5) {
						for (int q = 0; q < relationships.size(); q++) {
							if (relationships.get(q).a == p
									|| relationships.get(q).b == p) {
								relationships.remove(q);
								q--;
							}
						}
						pixels.remove(p);
					}
				}
			} else {
				boolean cont = true;
				for (Pixel i : pixels) {
					if (i.x > x - 5 && i.x < x + 5 && i.y < y + 5
							&& i.y > y - 5) {
						startPix = i;
						cont = false;
					}
				}
				if (cont) {
					startX = x;
					startY = y;
				}
			}
		}
	}

	public void release() {
		clicking = false;
		r1 = r2 = r3 = false;
		rigid1 = rigid2 = rigid3 = null;
		rigidPrev = new Pixel(null, -1, -1);
		index = -1;
		if (properties.rigid.isSelected() && draw && !erase) {
			return;
		}
		if (!draw) {
			for (Pixel p : pixels) {
				p.click(false);
			}
		} else {
			if (!erase) {
				frame.Currently.setText("Drawing");
				endX = MouseInfo.getPointerInfo().getLocation().x
						- frame.getX();
				endY = MouseInfo.getPointerInfo().getLocation().y
						- frame.getY();
				if (!(endX > startX - 2 && endX < startX + 2
						&& endY > startY - 2 && endY < startY + 2)) {
					for (Pixel i : pixels) {
						if (i.x > endX - 5 && i.x < endX + 5 && i.y < endY + 5
								&& i.y > endY - 5) {
							endPix = i;
						}
					}
					if (startPix == null) {
						if (properties.fixed.isSelected()) {
							startPix = new pixels.Fixed(Color.black, startX,
									startY);
							System.out.println("yay");
						} else {
							startPix = new Pixel(Color.red, startX, startY);
						}
						pixels.add(startPix);
					}
					if (endPix == null) {
						if (properties.fixed.isSelected()) {
							endPix = new pixels.Fixed(Color.black, endX, endY);
						} else {
							endPix = new Pixel(Color.red, endX, endY);
						}
						pixels.add(endPix);
					}
					endX = (int) endPix.x;
					endY = (int) endPix.y;
					startX = (int) startPix.x;
					startY = (int) startPix.y;
					int elasticity = 1;
					if (properties.elastic.isSelected()) {
						elasticity = 20;
					}
					relationships.add(new Relationship(startPix, endPix,
							(int) Math.sqrt((endX - startX) * (endX - startX)
									+ (endY - startY) * (endY - startY)),
							elasticity));
					if (invisible) {
						relationships.get(relationships.size() - 1).invisible = true;
					}
					relationships.get(relationships.size() - 1).manager = this;

				} else {
					if (properties.fixed.isSelected()) {
						pixels.add(new pixels.Fixed(Color.black, endX, endY));
					} else {
						pixels.add(new Pixel(Color.red, endX, endY));
					}
				}
				startPix = null;
				endPix = null;
				startX = startY = endX = endY = 0;
			} else {
				frame.Currently.setText("Erasing");
			}
		}
	}

	public void clear() {
		relationships = new ArrayList<Relationship>();
		pixels = new ArrayList<Pixel>();
	}
}
